package com.sxt.core.consumer.rpc;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.List;

import com.sxt.core.anno.AutoBuilder;
import com.sxt.core.anno.Inject;
import com.sxt.core.codc.Codecer;
import com.sxt.core.consumer.Discovery;
import com.sxt.core.model.Request;
import com.sxt.core.model.Response;
import com.sxt.core.net.NetClientService;
import com.sxt.core.proxy.MethodInvoke;
import com.sxt.core.util.ResourceUtil;

@AutoBuilder
public class RpcMethodInvoke implements MethodInvoke{

	@Inject
	private NetClientService netClientService;
	
	@Inject
	private Codecer coder;
	
	@Inject
	private Discovery disCovery;
	// 完成方法的调用
	@Override
	public Object invoke(Method method, Object[] args) {
		Object result = null ;
		
		
		// 给服务的提供者发送请求对象
		Request request = new Request();
		String interfaceName = method.getDeclaringClass().getName();
		request.setInterfaceName(interfaceName); // 获取当前方法在那个类里面  toString 
		request.setMethodName(method.getName());
		request.setAgrs(args);
		// 
		List<String> serverList = disCovery.discovery(interfaceName) ;
		netClientService.createConnection(serverList.get(0)); // 每次都要新建连接
		
		OutputStream outputStream  = null ;
		InputStream inputStream  = null;
		try {
			outputStream = netClientService.getOutputStream();
			// 发送数据的操作
			byte[] requestBs = coder.code(request);
			byte[]total = new byte[requestBs.length+1];//  length + 1 = -1
			System.arraycopy(requestBs, 0, total, 0, requestBs.length);
			total[total.length-1] = -1;  // 结束的标签
			//
			
			outputStream.write(total);
			outputStream.flush();
			
			inputStream = netClientService.getInputStream();
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
			byte []bs = new byte[2048];
			int len = 0 ;
			while((len=inputStream.read(bs))!=-1) {
				if(bs[len-1]!=-1) {
					byteArrayOutputStream.write(bs, 0, len); // 正常的写
				}else { //[1,2,-1]    [-1]
					if(len==1) { // 读最后一轮了，最后一个刚好是-1
						break ;
					}else {
						// 读最后一轮了，但是最后的还有有效数据，先把 有效数据读取出来
						byteArrayOutputStream.write(bs, 0, len-1);
						break ;
					}
					
				}
			}
			Response response = (Response)coder.deCode(byteArrayOutputStream.toByteArray());
			result = response.getResult();
			if(response.getError()!=null) {
				throw new RuntimeException(response.getError());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			ResourceUtil.closes(outputStream);
		}
		return result;
	}

}
